package com.rency.ues.webapp.controller;

import com.rency.ues.webapp.common.BaseAction;
import com.rency.ues.webapp.common.Constants;
import org.apache.commons.lang.StringUtils;
import org.rency.common.utils.security.X509CertUtils;
import org.rency.ues.common.UesDict;
import org.rency.ues.common.UesUtils;
import org.rency.ues.common.enums.EncryptType;
import org.rency.ues.common.model.EncryptData;
import org.rency.ues.domain.request.DecryptRequest;
import org.rency.ues.domain.request.EncryptRequest;
import org.rency.ues.domain.response.DecryptResponse;
import org.rency.ues.domain.response.EncryptResponse;
import org.rency.ues.domain.support.Certification;
import org.rency.ues.engine.manager.CertificationManager;
import org.rency.ues.engine.service.UesService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.security.PrivateKey;

/**
 * ${todo}
 *
 * @author: Created by user_rcy@163.com on 2016/8/1.
 * @version: V1.0.0
 * @since JDK 1.8
 */
@Controller
@RequestMapping("/ues")
public class UesController extends BaseAction{

    @Resource(name="uesService")
    private UesService uesService;

    @Resource(name="certificationManager")
    private CertificationManager certificationManager;

    @RequestMapping(value="encryptView.htm",method= RequestMethod.GET)
    public ModelAndView encryptView(){
        this.clear();
        return this.view(Constants.VM_PATH_PREFIX_UES,"encrypt");
    }

    @RequestMapping(value="encrypt.htm",method= RequestMethod.POST)
    public ModelAndView encrypt(HttpServletRequest request){
        String plainData = request.getParameter("plainData");
        if(StringUtils.isBlank(plainData)){
            this.failed("加密数据不能为空.");
            return this.view(Constants.VM_PATH_PREFIX_UES,"encrypt");
        }
        logger.info("加密请求");
        Certification certification = certificationManager.getCertification(null);
        EncryptData enData = null;
        try {
            enData = UesUtils.generateEncryptData(plainData, EncryptType.RSA,certification.getCertificate());
        } catch (Exception e) {
            logger.error("生成待加密数据密文异常.",e);
            this.failed(UesDict.CHINESE_FAIL_MSG);
            return this.view(Constants.VM_PATH_PREFIX_UES,"encrypt");
        }

        EncryptRequest eq = new EncryptRequest();
        eq.setSerialNo(enData.getSerialNo());
        eq.setEncryptedData(enData.getEncryptedData());
        eq.setEncryptedKey(enData.getEncryptedKey());
        eq.setEncryptType(enData.getEncryptType());
        EncryptResponse response = uesService.encrypt(eq);
        logger.debug("加密返回结果:{}.",response);
        if(!response.isSuccess()){
            logger.info("加密失败,rsponse:{}.",response);
            this.failed(response.getReturnMessage());
        }else{
            logger.info("加密成功,rsponse:{}.",response);
            respBody.put(UesDict.REST_PARAMETER_KEY_TICKET,response.getTicket());
            respBody.put(UesDict.REST_PARAMETER_KEY_PLAIN_DATA,plainData);
            this.success(response.getReturnMessage());
        }
        return this.view(Constants.VM_PATH_PREFIX_UES,"encrypt");
    }

    @RequestMapping(value="decryptView.htm",method= RequestMethod.GET)
    public ModelAndView decryptView(){
        this.clear();
        return this.view(Constants.VM_PATH_PREFIX_UES,"decrypt");
    }

    @RequestMapping(value="decrypt.htm",method= RequestMethod.POST)
    public ModelAndView decrypt(HttpServletRequest request){
        String ticket = request.getParameter("ticket");
        if(StringUtils.isBlank(ticket)){
            this.failed("密钥不能为空.");
            return this.view(Constants.VM_PATH_PREFIX_UES,"decrypt");
        }
        DecryptRequest deRequest = new DecryptRequest();
        deRequest.setTicket(ticket);
        DecryptResponse response = uesService.decrypt(deRequest);
        logger.debug("解密返回结果:{}.",response);
        if(!response.isSuccess()){
            logger.info("解密失败,rsponse:{}.",response);
            this.failed(response.getReturnMessage());
        }else{
            EncryptData enData = new EncryptData();
            enData.setEncryptedKey(response.getEncryptedKey());
            enData.setEncryptedData(response.getEncryptedData());
            enData.setEncryptType(response.getEncryptType());
            enData.setSerialNo(response.getSerialNo());
            try {
                PrivateKey privateKey = X509CertUtils.getPrivateKeyFromBase64String(response.getPrivateKey());
                String plainData = UesUtils.getPlainData(enData, this.certificationManager.getX509(enData.getSerialNo()), privateKey);
                if(StringUtils.isBlank(plainData)){
                    logger.info("解密失败,返回明文为空,rsponse:{}.",response);
                    this.failed(UesDict.CHINESE_FAIL_MSG);
                }
                logger.info("解密成功,rsponse:{}.",response);
                respBody.put(UesDict.REST_PARAMETER_KEY_TICKET,ticket);
                respBody.put(UesDict.REST_PARAMETER_KEY_PLAIN_DATA,plainData);
                this.success(response.getReturnMessage());
            } catch (Exception e) {
                logger.error("解密失败,解析密文未知异常.",e);
                this.failed(UesDict.CHINESE_FAIL_MSG);
            }
        }
        return this.view(Constants.VM_PATH_PREFIX_UES,"decrypt");
    }

}
